﻿using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;

using MyLibrary;

namespace MyLibrary.CommonTask
{
    /// <summary>
    /// 计划任务需要实现的接口
    /// </summary>
    public interface ISchedule
    {
        /// <summary>
        /// 计划任务开始的时间
        /// </summary>
        DateTime ExecuteBeginTime { get; set; }
        /// <summary>
        /// 任务开始时间与当前时间的差
        /// </summary>
        long DueTime { get; }
        /// <summary>
        /// 执行周期
        /// </summary>
        long Period { get; }
    }
    /// <summary>
    /// 实现立即执行计划任务
    /// </summary>
    public class ExecuteImmediate : ISchedule
    {
        #region ISchedule Members

        public DateTime ExecuteBeginTime
        {
            get
            {
                return DateTime.Now;
            }
            set
            {
                ;
            }
        }

        public long DueTime
        {
            get
            {
                return 0;
            }
        }

        public long Period
        {
            get { return Timeout.Infinite; }
        }

        #endregion
    }
    /// <summary>
    /// 只执行一次
    /// </summary>
    public class ExecuteOnce : ISchedule
    {
        private DateTime _schedule;
        public ExecuteOnce(DateTime schedule)
        {
            this._schedule = schedule;
        }


        #region ISchedule Members

        public DateTime ExecuteBeginTime
        {
            get
            {
                return _schedule;
            }
            set
            {
                _schedule = value;
            }
        }

        public long DueTime
        {
            get 
            {
                long ms = (_schedule.Ticks - DateTime.Now.Ticks) / 10000;
                if (ms < 0) ms = 0;
                return ms;
            }
        }

        public long Period
        {
            get { return Timeout.Infinite; }
        }

        #endregion
    }
    /// <summary>
    /// 循环执行
    /// </summary>
    public class ExecuteCycle : ISchedule
    {
        private DateTime _schedule;
        private TimeSpan _period;

        public ExecuteCycle(DateTime schedule, TimeSpan period)
        {
            _schedule = schedule;
            _period = period;
        }

        public ExecuteCycle(TimeSpan period)
        {
            _schedule = DateTime.Now;
            _period = period;
        }

        #region ISchedule Members

        public DateTime ExecuteBeginTime
        {
            get
            {
                return _schedule;
            }
            set
            {
                _schedule = value;
            }
        }

        public long DueTime
        {
            get
            {
                long ms = (_schedule.Ticks - DateTime.Now.Ticks) / 10000;
                if (ms < 0) ms = 0;
                return ms;
            }
        }

        public long Period
        {
            get { return _period.Ticks / 10000; }
        }

        #endregion
    }

    /// <summary>
    /// 实现计划任务的类
    /// </summary>
    public class ScheduleTask
    {
        private ISchedule _schedule;  //计划任务
        /// <summary>
        /// 任务计划
        /// </summary>
        public ISchedule Schedule
        {
            get { return _schedule; }
        }
        private DateTime _nextExecuteTime;  //执行任务的下一个是时刻
        /// <summary>
        /// 任务下一执行时间
        /// </summary>
        public DateTime NextExecuteTime
        {
            get { return _nextExecuteTime; }
        }
        private DateTime _lastExecuteTime;  //任务的最后一次执行时刻
        /// <summary>
        /// 任务最后一次执行的时间
        /// </summary>
        public DateTime LastExecuteTime
        {
            get { return _lastExecuteTime; }
        }
        private Timer _timer;  //定时器
        private TimerCallback _job;  //执行的任务

        public TimerCallback Job
        {
            get { return _job; }
            set { _job = value; }
        }
        private string _taskName;  //任务名称
        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName
        {
            get { return _taskName; }
            set { _taskName = value; }
        }
        private string _description;  //任务描述
        /// <summary>
        /// 任务描述
        /// </summary>
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }
        private object _params;   //任务参数
        /// <summary>
        /// 任务参数
        /// </summary>
        public object TaskParam
        {
            get { return _params; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="schedule">任务的执行计划</param>
        public ScheduleTask(ISchedule schedule)
        {
            if (schedule == null) throw new ArgumentNullException("执行计划不能为空");
            this._schedule = schedule; 
        }

        /// <summary>
        /// 启动任务
        /// </summary>
        public void Start()
        {
            //开启一个计时器
            _timer = new Timer(_job, _params, _schedule.DueTime, _schedule.Period);
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        public void Stop()
        {
            //停止计时器
            _timer.Change(Timeout.Infinite, Timeout.Infinite);
        }

        /// <summary>
        /// 开始执行任务
        /// </summary>
        public virtual void Execute(object param)
        {
            _lastExecuteTime = DateTime.Now;

            if (_schedule.Period == Timeout.Infinite)
                _nextExecuteTime = DateTime.MaxValue;
            else
            {
                TimeSpan period = new TimeSpan(_schedule.Period * 1000);
                _nextExecuteTime = _lastExecuteTime + period;
            }
        }
    }
    
    /// <summary>
    /// 任务调度中心,用于管理一个或多个任务
    /// </summary>
    public class TaskCenter
    {
        List<ScheduleTask> _scheduleTasks;

        /// <summary>
        /// 构造函数
        /// </summary>
        public TaskCenter()
        {
            this._scheduleTasks = new List<ScheduleTask>();
        }

        /// <summary>
        /// 添加新的任务
        /// </summary>
        /// <param name="newTask">新任务</param>
        public void AddTask(ScheduleTask newTask)
        {
            this._scheduleTasks.Add(newTask);
        }

        /// <summary>
        /// 移除一个任务
        /// </summary>
        /// <param name="delTask">要移除的任务</param>
        public void RemoveTask(ScheduleTask delTask)
        {
            this._scheduleTasks.Remove(delTask);
        }

        /// <summary>
        /// 启动所有任务
        /// </summary>
        public void StartAllTask()
        {
            foreach (ScheduleTask task in this._scheduleTasks)
                StartTask(task);
        }

        /// <summary>
        /// 启动一个任务
        /// </summary>
        /// <param name="task">要启动的任务</param>
        public void StartTask(ScheduleTask task)
        {
            if (task.Job == null)
                task.Job += new TimerCallback(task.Execute);
            task.Start();
        }

        /// <summary>
        /// 终止所有的任务
        /// </summary>
        public void StopAllTask()
        {
            foreach (ScheduleTask task in this._scheduleTasks)
                task.Stop();
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        /// <param name="task"></param>
        public void StopTask(ScheduleTask task)
        {
            task.Stop();
        }
    }

    /// <summary>
    /// 计时器
    /// </summary>
    public class TimeCounter : StartableBaseClass
    {
        object _syncObj = new object();
        long _startTime;
        long _spanTicks;

        /// <summary>
        /// 获得时间间隔的毫秒格式
        /// </summary>
        public long Milliseconds
        {
            get { return (long)(Ticks / 10000); }
        }

        /// <summary>
        /// 获取时间间隔的秒模式
        /// </summary>
        public long Seconds
        {
            get { return (long)(Ticks / 10000000); }
        }
        /// <summary>
        /// 获取从计时器启动到停止的时间间隔,如果计时器没有停止,则返回到当前时间的时间间隔
        /// </summary>
        public long Ticks
        {
            get
            {
                lock (_syncObj)
                {
                    if (!IsRun)
                        return _spanTicks;
                    else
                        return DateTime.Now.Ticks - _startTime;
                }
            }
        }

        public void Reset()
        {
            lock (_syncObj)
                _startTime = DateTime.Now.Ticks;
        }

        protected override void OnStart()
        {
            Reset();
        }

        protected override void OnStop()
        {
            lock (_syncObj)
                _spanTicks = DateTime.Now.Ticks - _startTime;
        }
    }
}
